package gates;

import java.awt.Graphics;

import master.QuantumRegister;

/**
 * Implementation of a Full Quantum Adder as a composite gate of two Simple Quantum Adders.
 * takes in 4 qBits of which 2 are control, a carryin and a carryout. 
 * reversible application provided through method.
 *
 * @author Oliver
 * 
 */
public class FullQuantumAdder extends QuantumGate{

	
	int carryin,control1,control2,carryout;
	QuantumAdder adder1, adder2;
	
	/**
	 * creates 2 Simple Adders and allocates the qBits accordingly
	 * @param carryin
	 * @param control1
	 * @param control2
	 * @param carryout
	 */
	public FullQuantumAdder(int carryin, int control1, int control2, int carryout){
		this.carryin = carryin;
		this.control1 = control1;
		this.control2 = control2;
		this.carryout = carryout;
		
		adder1 = new QuantumAdder(control1, control2, carryout);
		adder2 = new QuantumAdder(carryin,control2,carryout);
		
		
	}

	/**
	 * acts with this gate on the given Quantum Register
	 * @param register
	 */
	public void actOnReg(QuantumRegister register) {
		adder1.actOnReg(register);
		//printOut(register);
		
		adder2.actOnReg(register);
		//printOut(register);
		
	}
	/**
	 * acts with this gate in reverse on the given QuantumGate
	 * @param register
	 */
	public void actOnRegReverse(QuantumRegister register){
		adder2.actOnRegReverse(register);
		//printOut(register);
		adder1.actOnRegReverse(register);
		//printOut(register);
	}

	/**
	 * used for visual representation of the gate in the UI
	 */
	

	/**
	 * Returns a list with all the qBits the register acts on
	 */
	public int[] getActingBits() {
		int[] actingBits = new int[4];
		actingBits[0] = carryin;
		actingBits[1]= control1;
		actingBits[2]= control2;
		actingBits[3]= carryout;
		return actingBits;
	}
	
	
	/**
	 * prints out the register as states with coefficients
	 * used only for testing
	 * @param reg
	 */
	public static void printOut(QuantumRegister reg){
		for (int n=0;n<reg.getDimension();n++){
			if(reg.getCoefficient(n).magnitudeFloat()>0)
				System.out.println(" " + reg.getCoefficient(n) + "|" + Integer.toBinaryString(n) + "("+ n +")>");
		}
		System.out.println("");
	}

}
